home *** CD-ROM | disk | FTP | other *** search
/ La Traviata / La Traviata.iso / viewer / grabsc11.zip / TSR.ASM < prev    next >
Assembly Source File  |  1990-11-28  |  13KB  |  708 lines

  1. ;
  2. ;Routines to set up a program as TSR, by hooking the keyboard interrupt
  3. ;locally and testing the scancodes against given scancode hot key.
  4. ;This module was tested in TINY model only.
  5. ;This module is based on "MSDOS encyclopedia" snap.asm example pp 360-380.
  6. ;You may want to refer to that reference for more information.
  7. ;Unlike the original article we assume here DOS 3.1 or above.
  8. ;
  9. ; Defined functions (see also TSR.H):
  10. ;
  11. ; 1. int HookKbdInterrupt(void (*Func)(), unsigned int ScanCode);
  12. ;    Hook the keyboard interrupts so that Func is called if ScanCode is
  13. ;    detected. Returns:
  14. ;    0 - everything O.K..
  15. ;    1 - already installed.
  16. ;    2 - can not install (int 02fh ID is in use).
  17. ;
  18. ; Compile as "tasm tsr.asm/mx"
  19. ;
  20. ;            Written by Gershon Elber, Sep. 1990
  21. ;
  22.     dosseg
  23.  
  24.     public    _HookKbdInterrupt
  25.     public  _InstalledTSRSegment
  26.  
  27.     .model    tiny            ;select tiny model
  28.  
  29.     .code                ;TC-compatible code segment
  30.  
  31. MultiplexID    equ    'G'        ;Hopefully unique int 2FH ID value.
  32. TSRStackSize    equ    0100h        ;Resident stack size in bytes.
  33.  
  34. KB_FLAG        equ    017h
  35.  
  36. KBIns        equ    080h
  37. KBCaps        equ    040h
  38. KBNum        equ    020h
  39. KBScroll    equ    010h
  40. KBAlt        equ    008h
  41. KBCtl        equ    004h
  42. KBLeft        equ    002h
  43. KBRight        equ    001h
  44.  
  45. TRUE        equ    -1
  46. FALSE        equ    0
  47.  
  48. ;****************************************************************************
  49. ;Hook to activate the TSR application routine.                    *
  50. ;****************************************************************************
  51. DoTSRApplication proc    near
  52. ;
  53.     push    ds
  54.     push    ax
  55. ;
  56.     push    cs
  57.     pop    ds
  58.     mov    ax,cs
  59. ;
  60.     mov    PrevSP,sp        ;Save previous SS:SP and set ours.
  61.     mov    PrevSS,ss
  62.     mov    ss,ax
  63.     mov    sp,offset StackTop
  64. ;
  65.     push    es
  66.     push    bx
  67.     push    cx
  68.     push    dx
  69.     push    si
  70.     push    di
  71.     push    bp
  72. ;
  73.     cld
  74. ;
  75. ;Set up the interrupt trapping routines.
  76. ;
  77.     mov    cx,NTrap
  78.     mov    si,offset StartTrapList
  79. DoTSR1:    lodsb
  80. ;
  81.     mov    byte ptr [si],FALSE    ;Zero the trap flag.
  82. ;
  83.     push    ax
  84.     mov    ah,035h            ;Get old interrupt vector.
  85.     int    021h            ;/
  86.     mov    [si+1],bx        ;And save it.
  87.     mov    [si+3],es        ;/
  88.     pop    ax
  89. ;
  90.     mov    dx,[si+5]        ;ds:dx hold out interrupt handler.
  91.     mov    ah,025h            ;Set new interrupt vector.
  92.     int    021h            ;/
  93. ;
  94.     add    si,007
  95.     loop    DoTSR1
  96. ;
  97.     mov    ax,03300h        ;Disable break during disk I/O.
  98.     int    021h            ; |
  99.     mov    PrevBreak,dl        ; |
  100.     xor    dl,dl            ; |
  101.     mov    ax,03301h        ; |
  102.     int    021h            ;/
  103. ;
  104. ;Preserve previous extrended error information.
  105. ;
  106.     push    ds
  107.     xor    bx,bx
  108.     mov    ah,059h            ;Get extrended error info
  109.     int    021h
  110.     mov    cs:PrevExtErrDs,ds
  111.     pop    ds
  112.     mov    PrevExtErrAx,ax
  113.     mov    PrevExtErrBx,bx
  114.     mov    PrevExtErrCx,cx
  115.     mov    PrevExtErrDx,dx
  116.     mov    PrevExtErrSi,si
  117.     mov    PrevExtErrDi,di
  118.     mov    PrevExtErrEs,es
  119. ;
  120.     mov    ah,051h            ;Get current PSP
  121.     int    021h            ; |
  122.     mov    PrevPSP,bx        ;/
  123. ;
  124.     mov    bx,TSRPSP        ;Set our PSP
  125.     mov    ah,050h            ; |
  126.     int    021h            ;/
  127. ;
  128.     mov    ah,02fh            ;Get DTA address
  129.     int    021h            ; |
  130.     mov    PrevDTAoffs,bx        ; |
  131.     mov    PrevDTAseg,es        ;/
  132. ;
  133.     push    ds
  134.     mov    ds,TSRPSP
  135.     mov    dx,00080h        ;ds:dx is new DTA.
  136.     mov    ah,01ah            ;Set DTA address.
  137.     int    021h            ;/
  138.     pop    ds
  139. ;
  140.     mov    byte ptr cs:ActiveTSR,TRUE
  141. ;
  142.     mov    ax,00e07h        ;Do some noise
  143.     int    010h            ;/
  144. ;
  145.     call    word ptr [FuncAddr]
  146. ;
  147.     mov    ax,00e07h        ;Do some noise
  148.     int    010h            ;/
  149.     mov    byte ptr cs:ActiveTSR,FALSE
  150. ;
  151.     push    ds
  152.     lds    dx,PrevDTA        ;Restore DTA.
  153.     mov    ah,01ah            ;Set DTA address.
  154.     int    021h            ;/
  155.     pop    ds
  156. ;
  157.     mov    bx,PrevPSP        ;Restore PSP.
  158.     mov    ah,050h            ;Set PSP address.
  159.     int    021h            ;/
  160. ;
  161.     mov    dx,offset PrevExtErrInfo ;Restore extended error information
  162.     mov    ax,05d0ah        ; |
  163.     int    021h            ;/
  164. ;
  165.     mov    dl,PrevBreak        ;Restore previous MSDOS break status.
  166.     mov    ax,03301h        ; |
  167.     int    021h            ;/
  168. ;
  169.     mov    cx,NTrap
  170.     mov    si,offset StartTrapList
  171.     push    ds
  172. ;
  173. DoTSR5: lods    byte ptr cs:[si]    ;Restore previous traps.
  174.     lds    dx,cs:[si+1]
  175.     mov    ah,025h
  176.     int    021h
  177.     add    si,00007h
  178.     loop    DoTSR5
  179. ;
  180.     pop    ds
  181. ;
  182.     pop    bp
  183.     pop    di
  184.     pop    si
  185.     pop    dx
  186.     pop    cx
  187.     pop    bx
  188.     pop    es
  189. ;
  190.     mov    ss,PrevSS
  191.     mov    sp,PrevSP
  192. ;
  193.     pop    ax
  194.     pop    ds
  195. ;
  196.     mov    byte ptr cs:HotFlag,FALSE
  197. ;
  198.     ret
  199. ;
  200. DoTSRApplication    endp
  201.  
  202. ;
  203. ;****************************************************************************
  204. ;This Function verifies we are not in DOS.                    *
  205. ;****************************************************************************
  206. VerifyDOSState    proc    near
  207. ;
  208.     push    ds
  209.     push    bx
  210.     push    ax
  211. ;
  212.     lds    bx,cs:ErrorModeAddr
  213.     mov    ah,[bx]
  214. ;
  215.     lds    bx,cs:InDosAddr
  216.     mov    al,[bx]
  217. ;
  218.     xor    bx,bx
  219.     cmp    bl,cs:InISR28
  220. ;
  221.     rcl    bl,01h
  222. ;
  223.     cmp    bx,ax
  224. ;
  225.     pop    ax
  226.     pop    bx
  227.     pop    ds
  228. ;
  229.     ret
  230. ;
  231. VerifyDOSState    endp
  232.  
  233. ;****************************************************************************
  234. ;This Function verifies we are not in BIOS.                    *
  235. ;****************************************************************************
  236. VerifyIntState    proc    near
  237. ;
  238.     push    ax
  239. ;
  240.     mov    ax,000001011b    ;RR = 1, RIS = 1.
  241.     out    020h,al
  242.     jmp    short VerInt1    ;Buy some time.
  243. VerInt1:in    al,020h
  244.     cmp    ah,al
  245.     jc    short VerInt2    ;Hardware interrupt is been serviced?
  246. ;
  247.     xor    al,al
  248.     cmp    al,cs:InISR5
  249.     jc    short VerInt2
  250. ;
  251.     cmp    al,cs:InISR9
  252.     jc    short VerInt2
  253. ;
  254.     cmp    al,cs:InISR10
  255.     jc    short VerInt2
  256. ;
  257.     cmp    al,cs:InISR13
  258. ;
  259. VerInt2:pop    ax
  260. ;
  261.     ret
  262. ;
  263. VerifyIntState    endp
  264.  
  265. ;****************************************************************************
  266. ;This Function verifies we are not in DOS/BIOS.                    *
  267. ;****************************************************************************
  268. VerifyTSRState    proc    near
  269. ;
  270.     ror    cs:HotFlag,1    ;Hot key has been pressed?
  271.     cmc
  272.     jc    short VerTSR1
  273. ;
  274.     ror    cs:ActiveTSR,1    ;Are we in the middle of serving our TSR?
  275.     jc    short VerTSR1
  276. ;
  277.     call    VerifyDOSState
  278.     jc    short VerTSR1
  279. ;
  280.     call    VerifyIntState
  281. ;
  282. VerTSR1:ret
  283. ;
  284. VerifyTSRState    endp
  285.  
  286. ;****************************************************************************
  287. ;The following routines monitor activity in different interrupt vectors.    *
  288. ;****************************************************************************
  289. ISR5    proc    far
  290. ;
  291.     inc    cs:InISR5
  292. ;
  293.     pushf
  294.     cli
  295.     call    cs:PrevISR5
  296. ;
  297.     dec    cs:InISR5
  298. ;
  299.     iret
  300. ;
  301. ISR5    endp
  302.  
  303. ;****************************************************************************
  304. ISR8    proc    far
  305. ;
  306.     pushf
  307.     cli
  308.     call    cs:PrevISR8
  309. ;
  310.     cmp    cs:InISR8,0
  311.     jne    short ISR8b        ;Exit if already in this handler.
  312. ;
  313.     inc    cs:InISR8
  314. ;
  315.     sti
  316.     call    VerifyTSRState
  317.     jc    short ISR8a
  318. ;
  319.     call    DoTSRApplication
  320. ;
  321. ISR8a:    dec    cs:InISR8
  322. ;
  323. ISR8b:    iret
  324. ;
  325. ISR8    endp
  326.  
  327. ;****************************************************************************
  328. ISR9    proc    far
  329. ;
  330.     push    ds
  331.     push    ax
  332.     push    bx
  333. ;
  334.     push    cs
  335.     pop    ds
  336. ;
  337.     in    al,060h
  338. ;
  339.     pushf
  340.     cli
  341.     call    cs:PrevISR9
  342. ;
  343.     mov    ah,ds:InISR9
  344.     or    ah,ds:HotFlag
  345.     jnz    short ISR9d
  346. ;
  347.     inc    ds:InISR9
  348.     sti
  349. ;
  350.     cmp    ds:HotSeqLen,0
  351.     je    short ISR9a
  352. ;
  353.     mov    bx,ds:HotIndex
  354.     cmp    al,[bx+HotSequence]
  355.     jne    short ISR9b
  356. ;
  357.     inc    bx
  358.     cmp    bx,ds:HotSeqLen
  359.     jb    short ISR9c
  360. ;
  361. ISR9a:    push    ds
  362.     mov    ax,0040h
  363.     mov    ds,ax
  364.     mov    al,ds:[KB_FLAG]
  365.     pop    ds
  366. ;
  367.     and    al,ds:HotKbMask
  368.     cmp    al,ds:HotKBFlag
  369.     jne    short ISR9c
  370. ;
  371.     mov    byte ptr ds:HotFlag,TRUE
  372. ;
  373. ISR9b:    xor    bx,bx
  374. ;
  375. ISR9c:    mov    ds:HotIndex,bx
  376.     dec    ds:InISR9
  377. ;
  378. ISR9d:    pop    bx
  379.     pop    ax
  380.     pop    ds
  381. ;
  382.     iret
  383. ;
  384. ISR9    endp
  385.  
  386. ;****************************************************************************
  387. ISR10    proc    far
  388. ;
  389.     inc    cs:InISR10
  390. ;
  391.     pushf
  392.     cli
  393.     call    cs:PrevISR10
  394. ;
  395.     dec    cs:InISR10
  396. ;
  397.     iret
  398. ;
  399. ISR10    endp
  400.  
  401. ;****************************************************************************
  402. ISR13    proc    far
  403. ;
  404.     inc    cs:InISR13
  405. ;
  406.     pushf
  407.     cli
  408.     call    cs:PrevISR13
  409. ;
  410.     pushf
  411.     dec    cs:InISR13
  412.     popf
  413. ;
  414.     sti
  415.     ret    2
  416. ;
  417. ISR13    endp
  418.  
  419. ;****************************************************************************
  420. ISR1B    proc    far
  421. ;
  422.     mov    byte ptr cs:Trap1B,TRUE
  423. ;
  424.     iret
  425. ;
  426. ISR1B    endp
  427.  
  428. ;****************************************************************************
  429. ISR23    proc    far
  430. ;
  431.     mov    byte ptr cs:Trap23,TRUE
  432. ;
  433.     iret
  434. ;
  435. ISR23    endp
  436.  
  437. ;****************************************************************************
  438. ISR24    proc    far
  439. ;
  440.     mov    byte ptr cs:Trap24,TRUE
  441. ;
  442.     mov    al,3            ;fail the MSDOS call.
  443. ;
  444.     iret
  445. ;
  446. ISR24    endp
  447.  
  448. ;****************************************************************************
  449. ISR28    proc    far
  450. ;
  451.     pushf
  452.     cli
  453.     call    cs:PrevISR28
  454. ;
  455.     cmp    cs:InISR28,0
  456.     jne    short ISR28b
  457. ;
  458.     inc    cs:InISR28
  459. ;
  460.     call    VerifyTSRState
  461.     jc    short ISR28a
  462. ;
  463.     call    DoTSRApplication
  464. ;
  465. ISR28a:    dec    cs:InISR28
  466. ;
  467. ISR28b:    iret
  468. ;
  469. ISR28    endp
  470.  
  471. ;****************************************************************************
  472. ISR2F    proc    far
  473. ;
  474.     cmp    ah,MultiplexID
  475.     je    short ISR2Fa
  476. ;
  477.     jmp    cs:PrevISR2F
  478. ;
  479. ISR2Fa:    test    al,al
  480.     jnz    short ISR2Fb
  481. ;
  482.     mov    al,0ffh
  483.     mov    bx,cs            ;Return the installed TSR segment.
  484. ;
  485. ISR2Fb:    iret
  486. ;
  487. ISR2F    endp
  488.  
  489. ;****************************************************************************
  490. ; Data section:                                    *
  491. ;****************************************************************************
  492.     .data?                ;TC-comp. uninitialized data segment.
  493.  
  494. _InstalledTSRSegment    dw    ?    ;If already installed - segment addr.
  495.  
  496. ErrorModeAddr    dd    ?        ;MSDOS ErrorMode flag address.
  497. InDosAddr    dd    ?        ;MSDOS InDOS flag address.
  498. ;
  499. NISR        dw    (EndISRList-StartISRList) / 8    ;# of installed ISRs.
  500. ;
  501. StartISRList    db    005h        ;Int number.
  502. InISR5        db    FALSE
  503. PrevISR5    dd    ?
  504.         dw    offset ISR5
  505. ;
  506.         db    008h        ;Int number.
  507. InISR8        db    FALSE
  508. PrevISR8    dd    ?
  509.         dw    offset ISR8
  510. ;
  511.         db    009h        ;Int number.
  512. InISR9        db    FALSE
  513. PrevISR9    dd    ?
  514.         dw    offset ISR9
  515. ;
  516.         db    010h        ;Int number.
  517. InISR10        db    FALSE
  518. PrevISR10    dd    ?
  519.         dw    offset ISR10
  520. ;
  521.         db    013h        ;Int number.
  522. InISR13        db    FALSE
  523. PrevISR13    dd    ?
  524.         dw    offset ISR13
  525. ;
  526.         db    028h        ;Int number.
  527. InISR28        db    FALSE
  528. PrevISR28    dd    ?
  529.         dw    offset ISR28
  530. ;
  531.         db    02fh        ;Int number.
  532. InISR2f        db    FALSE
  533. PrevISR2f    dd    ?
  534.         dw    offset ISR2f
  535. ;
  536. EndISRList    label    byte
  537. ;
  538. TSRPSP        dw    ?        ;Resident PSP
  539. PrevPSP        dw    ?        ;Previous PSP
  540. PrevSP        dw    ?        ;Previous SS:SP
  541. PrevSS        dw    ?
  542. ;
  543. PrevBreak    db    ?
  544. ;
  545. PrevDTA        label    dword
  546. PrevDTAoffs    dw    ?
  547. PrevDTAseg    dw    ?
  548. ;
  549. HotIndex    dw    0        ;Index of next scancode in seq.
  550. HotSeqLen    dw    EndHotSeq-HotSequence    ;Length of hot keys seq.
  551. ;
  552. HotSequence    db    ?        ;Hot sequence of scan codes.
  553. EndHotSeq    label    byte
  554. ;
  555. HotKBFlag    db    ?
  556. HotKBMask    db    (KBIns or KBCaps or KBNum or KBScroll) xor 0ffh
  557. HotFlag        db    FALSE
  558. ;
  559. ActiveTSR    db    FALSE
  560. ;
  561. DOSVersion    label    word
  562.         db    ?        ;Minor version number.
  563. MajorVersion    db    ?        ;Major version number.
  564. ;
  565. ;Data used by the TSR application trapping.
  566. ;
  567. PrevExtErrInfo    label    byte
  568. PrevExtErrAx    dw    ?
  569. PrevExtErrBx    dw    ?
  570. PrevExtErrCx    dw    ?
  571. PrevExtErrDx    dw    ?
  572. PrevExtErrSi    dw    ?
  573. PrevExtErrDi    dw    ?
  574. PrevExtErrDs    dw    ?
  575. PrevExtErrEs    dw    ?
  576.         dw    3 dup(0)
  577. ;
  578. NTrap        dw    (EndTrapList-StartTrapList) / 8
  579. ;
  580. StartTrapList    db    01bh
  581. Trap1B        db    FALSE
  582. PrevISR1B    dd    ?
  583.         dw    offset ISR1B
  584. ;
  585.         db    023h
  586. Trap23        db    FALSE
  587. PrevISR23    dd    ?
  588.         dw    offset ISR23
  589. ;
  590.         db    024h
  591. Trap24        db    FALSE
  592. PrevISR24    dd    ?
  593.         dw    offset ISR24
  594. ;
  595. EndTrapList    label    byte
  596. ;
  597. FuncAddr    dw    ?        ;Address of TSR application.
  598.  
  599. ;****************************************************************************
  600. ; Stack to be used by the resident section (in code segment...):        *
  601. ;****************************************************************************
  602.     .code
  603.  
  604.     db    TSRStackSize dup("Stack   ")
  605. StackTop    label    word
  606.  
  607. ;****************************************************************************
  608. ; Transient code - called only once in initialization process.            *
  609. ;****************************************************************************
  610.     .code
  611.  
  612. ;****************************************************************************
  613. ;This Function hooks the keyboard interrupt handler to ours, and save        *
  614. ;the requested scancode and function to call for it.                *
  615. ;Returns 0 in ax if O.k. otherwise error code (see header of this file.     *
  616. ;****************************************************************************
  617. _HookKbdInterrupt    proc    near
  618. ;
  619.     push    bp
  620.     mov    bp,sp
  621.     push    bx
  622.     push    cx
  623.     push    dx
  624.     push    si
  625.     push    di
  626.     push    es
  627.     push    ds
  628. ;
  629.     mov    ax,[bp+6]        ;Get scan code to compare with.
  630.     mov    byte ptr HotKBFlag,al    ; |
  631.     mov    byte ptr HotSequence,ah    ;/
  632. ;
  633.     mov    ax,[bp+4]        ;Get Func address.
  634.     mov    word ptr FuncAddr,ax    ;/
  635. ;
  636.     mov    ax,cs
  637.     mov    ds,ax
  638. ;
  639.     mov    TSRPSP,cs
  640. ;
  641.     mov    ah,030h            ;Get dos version.
  642.     int    021h            ; |
  643.     xchg    ah,al            ; |
  644.     mov    DosVersion,ax        ;/
  645. ;
  646.     mov    ah,MultiplexID        ;Verify its not already installed.
  647.     xor    al,al            ; |
  648.     int    02fh            ; |
  649.     test    al,al            ; |
  650.     jz    short Hook3        ; |
  651.     cmp    al,0ffh            ; |
  652.     jne    short Hook2        ; |
  653.     mov    ax,00001h        ; | Already installed.
  654.     mov    _InstalledTSRSegment,bx ; | Save installed TSR segment.
  655.     jmp    short Hook9        ; |
  656. Hook2:    mov    ax,00002h        ; | Can not install.
  657.     jmp    short Hook9        ;/
  658. ;
  659. Hook3:    mov    ah,034h            ;Get InDOS address.
  660.     int    021h            ; |
  661.     mov    word ptr InDOSAddr,bx    ; |
  662.     mov    word ptr InDOSAddr+2,es    ; |
  663.     dec    bx            ; | Error mode is just before it.
  664.     mov    word ptr ErrorModeAddr,bx    ; |
  665.     mov    word ptr ErrorModeAddr+2,es    ;/
  666. ;
  667.     mov    cx,NISR
  668.     mov    si,offset StartISRList
  669. Hook4:    lodsb
  670. ;
  671.     push    ax
  672.     mov    ah,035h            ;Get old interrupt vector.
  673.     int    021h            ; |
  674.     mov    [si+1],bx        ; | And save it
  675.     mov    [si+3],es        ;/
  676.     pop    ax
  677. ;
  678.     push    ds
  679.     mov    dx,[si+5]
  680.     push    cs
  681.     pop    ds
  682.     mov    ah,025h            ;Set our interrupt vector
  683.     int    021h            ;/
  684.     pop    ds
  685.     add    si,00007h
  686.     loop    Hook4
  687. ;
  688.     mov    es,cs:[02ch]        ;Free the environment.
  689.     mov    ah,049h            ; |
  690.     int    021h            ;/
  691. ;
  692.     xor    ax,ax
  693. ;
  694. Hook9:    pop    ds
  695.     pop    es
  696.     pop    di
  697.     pop    si
  698.     pop    dx
  699.     pop    cx
  700.     pop    bx
  701.     pop    bp
  702. ;
  703.     ret
  704. ;
  705. _HookKbdInterrupt    endp
  706.  
  707.     end
  708.